﻿#include "pch.h"
#include "MainPage.xaml.h"
#if __has_include("MainPage.g.cpp")
#include "MainPage.g.cpp"
#endif
#include <filesystem>
#include "Utils.h"

using AutoSuggestionBoxTextChangeReason = winrt::Microsoft::UI::Xaml::Controls::AutoSuggestionBoxTextChangeReason;

namespace winrt::NovelReader::implementation
{
    MainPage::MainPage()
    {
        m_viewModel = winrt::NovelReader::MainPageViewModel();
        m_userSettings = winrt::NovelReader::AppService::UserSettings(); 
        m_timer = winrt::Microsoft::UI::Xaml::DispatcherTimer(); 
        m_timer.Interval(std::chrono::seconds{5}); 
        m_timer.Tick({this, &MainPage::OnTimerTick});         
    }

    void MainPage::InitializeComponent()
    {
        MainPageT::InitializeComponent();
        m_viewModel.PropertyChanged({ this, &MainPage::OnViewModelPropertiesChanged });
    }

    winrt::NovelReader::MainPageViewModel MainPage::ViewModel()
    {
        return m_viewModel;
    }

    void MainPage::AutoSuggestBox_TextChanged(
        winrt::Microsoft::UI::Xaml::Controls::AutoSuggestBox const& sender, winrt::Microsoft::UI::Xaml::Controls::AutoSuggestBoxTextChangedEventArgs const& args)
    {
        if (m_viewModel.BookChapters() == nullptr) {
            return;
        }
        if (args.Reason() == AutoSuggestionBoxTextChangeReason::UserInput) {
            std::wstring input{ sender.Text() };
            auto suggestionItems = winrt::single_threaded_observable_vector<winrt::NovelReader::Chapter>();

            for (auto chapter : m_viewModel.BookChapters()) {
                std::wstring title{ chapter.Title() };

                if (title.find(input) != std::wstring::npos) {
                    suggestionItems.Append(chapter);
                    if (suggestionItems.Size() == 8) break;
                }
            }

            sender.ItemsSource(suggestionItems);
        }
    }

    void MainPage::AutoSuggestBox_SuggestionChosen(
        winrt::Microsoft::UI::Xaml::Controls::AutoSuggestBox const& sender, winrt::Microsoft::UI::Xaml::Controls::AutoSuggestBoxSuggestionChosenEventArgs const& args)
    {
        auto chapter = args.SelectedItem().as<winrt::NovelReader::Chapter>();
        this->m_titlesListView().SelectedItem(chapter);
        this->m_titlesListView().ScrollIntoView(chapter);
        sender.Text(L"");
    }

    void MainPage::Page_ActualThemeChanged(
        winrt::Microsoft::UI::Xaml::FrameworkElement const&, winrt::Windows::Foundation::IInspectable const&)
    {
        this->ViewModel().RaisePropertyChanged(L"ThemeStyle");
    }

    void MainPage::ScrollReader(winrt::NovelReader::ScrollDirection direction)
    {
        if (m_viewModel.BookChapters() == nullptr) {
            return;
        }

        switch (direction)
        {
        case winrt::NovelReader::ScrollDirection::Up:
            this->ChapterTextScrollView().ScrollBy(0, -280);
            break;
        case winrt::NovelReader::ScrollDirection::Down:
            this->ChapterTextScrollView().ScrollBy(0, 280);
            break;
        case winrt::NovelReader::ScrollDirection::Left:
            this->GotoPreviousChapter(); 
            break;
        case winrt::NovelReader::ScrollDirection::Right:
            this->GotoNextChapter(); 
            break;
        default:
            break;
        }
    }

    void MainPage::OnViewModelPropertiesChanged(
        winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventArgs const& args)
    {
        if (args.PropertyName() == L"SelectedChapter") {
            if (m_viewModel.SelectedChapter() == nullptr) {
                return; 
            }

            double yOffset = 0.0; 
            if (m_isFirst) {
                auto index = m_viewModel.SelectedChapter().Index(); 
                if (index > 0) {
                    yOffset = m_userSettings.LastReadingPosition(); 
                }
                m_isFirst = false; 
            }
            this->ChapterTextScrollView().ScrollTo(0, yOffset);
            this->m_titlesListView().ScrollIntoView(m_viewModel.SelectedChapter());
        }
        else if (args.PropertyName() == L"DisplayText") {
            this->UpdateRichTextBlock(); 
        }
    }

    void MainPage::EnableAutoTurnPage(bool value)
    {
        if (value) {
            m_timer.Start();
        }
        else {
            m_timer.Stop(); 
        }
    }

    void MainPage::UpdateRichTextBlock()
    {
        if (m_viewModel.BookChapters().Size() == 0) {
            return; 
        }

        this->DisplayTextBlock().Blocks().Clear();
        auto lines = Service::SplitTextAndAddWhiteLines(m_viewModel.SelectedChapter().Text(), m_userSettings.WhiteLines());
        for (auto& line : lines) {
            auto paragraph = winrt::Microsoft::UI::Xaml::Documents::Paragraph();
            auto run = winrt::Microsoft::UI::Xaml::Documents::Run();
            run.Text(line);
            paragraph.Inlines().Append(run);
            this->DisplayTextBlock().Blocks().Append(paragraph);
        }
    }

    void MainPage::OnTimerTick(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::Foundation::IInspectable const&)
    {
        if (m_viewModel.BookChapters().Size() == 0) {
            return; 
        }
        auto yOffset = m_userSettings.AutoTurnPageSpeed() * 3;
        this->ChapterTextScrollView().ScrollBy(0, yOffset); 
        if (m_isChapterFinished) {
            this->GotoNextChapter(); 
            m_isChapterFinished = false; 
        }
    }

    void MainPage::GotoPreviousChapter()
    {
        auto selectedIndex = m_viewModel.SelectedChapter().Index();
        if (selectedIndex == 0) {
            return;
        }
        auto newIndex = selectedIndex - 1; 
        auto selectedChapter = m_viewModel.BookChapters().GetAt(newIndex);
        m_viewModel.SelectedChapter(selectedChapter);

    }

    void MainPage::GotoNextChapter()
    {
        auto selectedIndex = m_viewModel.SelectedChapter().Index();
        auto totalChapters = static_cast<int32_t>(m_viewModel.BookChapters().Size());
        if (selectedIndex == totalChapters - 1) {
            if (m_timer.IsEnabled()) {
                m_timer.Stop();
            }
            return; 
        }
        auto newIndex = selectedIndex + 1; 
        auto selectedChapter = m_viewModel.BookChapters().GetAt(newIndex);
        m_viewModel.SelectedChapter(selectedChapter);
    }

    void MainPage::ChapterTextScrollView_ViewChanged(
        winrt::Microsoft::UI::Xaml::Controls::ScrollView const&, winrt::Windows::Foundation::IInspectable const&)
    {
        double offset = this->ChapterTextScrollView().VerticalOffset(); 
        m_userSettings.LastReadingPosition(offset); 
        double maxOffset = this->ChapterTextScrollView().ScrollableHeight(); 
        if (offset >= maxOffset - 0.5) {
            m_isChapterFinished = true; 
        }
    }
}



